package controllers

import auth.AuthActionWrapper
import dao._
import models.Tables._
import org.joda.time.DateTime
import play.api.mvc.{AbstractController, ControllerComponents}
import tool.Tool
import utils.Utils

import javax.inject.Inject
import scala.concurrent.ExecutionContext.Implicits.global
import scala.concurrent.Future
import implicits.Implicits._
import shared.pojo.{Pojo, Role}
import shared.pojo.Pojo.{ValidData, sampleId}
import upickle.default._
import auth.AuthTool._
import shared.pojo.Sample.{IdStrData, IdStrsData}

/**
 * Created by Administrator on 2019/8/7
 */
class SampleIdController @Inject()(cc: ControllerComponents)(
  implicit val accountDao: AccountDao,
  implicit val wechatMemberDao: WechatMemberDao,
  implicit val sampleIdDao: SampleIdDao,
  implicit val sampleDao: SampleDao,
  implicit val authAction: AuthActionWrapper,
) extends
  AbstractController(cc) {

  import Pojo.sampleId._

  def getNewIds = authAction(List(Role.Member, Role.Admin)).async { implicit request =>
    val data = Tool.transformRq.transform(reader[GetNewIds.Request])
    sampleIdDao.selectAll.flatMap { x =>
      val dbIds = x.map(_.id).toList

      def loop(dbIds: List[String], newIds: List[String]): List[String] = {
        if (newIds.isEmpty || (newIds ::: dbIds).nonUniq) {
          val curNewIds = (1 to data.num).map { curI =>
            Tool.productValidCode
          }.toList
          loop(dbIds, curNewIds)
        } else newIds
      }

      val newIds = loop(dbIds, List.empty)

      val rows = newIds.map { id =>
        SampleIdRow(id = id, memberAccount = data.account, downloadTime = new DateTime())
      }
      sampleIdDao.updates(rows).map { x =>
        Ok(writeJs(newIds))
      }
    }
  }

  def add2Db = authAction(List(Role.Admin, Role.Member)).async { implicit request =>
    val data = Tool.transformRq.transform(reader[Add2Db.Request])
    val rows = data.ids.map { id =>
      SampleIdRow(id = id, memberAccount = data.account, downloadTime = new DateTime())
    }
    sampleIdDao.updates(rows).map { x =>
      val response = ValidData(valid = true)
      Ok(writeJs(response))
    }
  }

  def all = authAction(List(Role.Admin, Role.Member)).async { implicit request =>
    sampleIdDao.selectAll.zip(sampleDao.selectAllId).map { case (x, sampleIds) =>
      val array = x.map { x =>
        val status = if (sampleIds.contains(x.id)) {
          "已使用"
        } else "未使用"
        writeJs(x).toObj ++ ujson.Obj("status" -> status)
      }
      Ok(writeJs(array))
    }
  }

  def sampleIdCheck = Action.async { implicit request =>
    val data = Tool.transformRq.transform(reader[SampleIdCheck.Request])
    sampleIdDao.selectOp(data.sampleId).map { op =>
      op match {
        case Some(y) => Ok(ujson.Obj("valid" -> false))
        case None =>
          Ok(ujson.Obj("valid" -> true))
      }
    }
  }

  def delete = authAction(List(Role.Admin, Role.Member)).async { implicit request =>
    val data = Tool.transformRq.transform(reader[IdStrData])
    val sampleIdF = sampleIdDao.delete(data.id)
    sampleIdF.map { x =>
      val response = ValidData(valid = true)
      Ok(writeJs(response))
    }
  }

  def deletes = authAction(List(Role.Admin, Role.Member)).async {
    implicit request =>
      val data = Tool.transformRq.transform(reader[IdStrsData])
      sampleIdDao.deletes(data.ids).map { x =>
        val response = ValidData(valid = true)
        Ok(writeJs(response))
      }
  }


}
